package com.ruoyi.project.service.impl;

import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.examination.util.SnowflakeIdUtils;
import com.ruoyi.project.common.A08TypeCommon;
import com.ruoyi.project.domain.A05Project;
import com.ruoyi.project.domain.A08PaymentReceipt;
import com.ruoyi.project.mapper.A05ProjectMapper;
import com.ruoyi.project.mapper.A08PaymentReceiptMapper;
import com.ruoyi.project.service.IA05ProjectService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 项目库Service业务层处理
 * 
 * @author WorrilessGo
 * @date 2025-11-18
 */
@Service
@Slf4j
public class A05ProjectServiceImpl implements IA05ProjectService 
{
    @Resource
    private A05ProjectMapper a05ProjectMapper;

    @Resource
    A08PaymentReceiptMapper a08PaymentReceiptMapper;

    /**
     * 查询项目库
     * 
     * @param projectId 项目库主键
     * @return 项目库
     */
    @Override
    public A05Project selectA05ProjectByProjectId(String projectId)
    {
        return a05ProjectMapper.selectA05ProjectByProjectId(projectId);
    }

    /**
     * 查询项目库列表
     * 
     * @param a05Project 项目库
     * @return 项目库
     */
    @Override
    public List<A05Project> selectA05ProjectList(A05Project a05Project)
    {
        return a05ProjectMapper.selectA05ProjectList(a05Project);
    }


    /**
     * 所有的项目编码
     *
     * @param a05Project 项目库
     * @return 项目库
     */
    @Override
    public List<String> selectA05ProjectCode(A05Project a05Project)
    {
        return  a05ProjectMapper.selectA05ProjectCode(a05Project);
    }


    /**
     * 新增项目库
     * 
     * @param a05Project 项目库
     * @return 结果
     */
    @Override
    public int insertA05Project(A05Project a05Project)
    {
        a05Project.setCreateTime(DateUtils.getNowDate());
        String id = String.valueOf(new SnowflakeIdUtils(5, 8).nextId());
        a05Project.setProjectId(id);
        a05Project.setCreateBy(SecurityUtils.getUsername());

        return a05ProjectMapper.insertA05Project(a05Project);
    }

    /**
     * 修改项目库
     * 
     * @param a05Project 项目库
     * @return 结果
     */
    @Override
    public int updateA05Project(A05Project a05Project)
    {
        a05Project.setUpdateTime(DateUtils.getNowDate());
        a05Project.setUpdateBy(SecurityUtils.getUsername());
        return a05ProjectMapper.updateA05Project(a05Project);
    }

    /**
     * 批量删除项目库
     * 
     * @param projectIds 需要删除的项目库主键
     * @return 结果
     */
    @Override
    public int deleteA05ProjectByProjectIds(String[] projectIds)
    {
        return a05ProjectMapper.deleteA05ProjectByProjectIds(projectIds);
    }

    /**
     * 删除项目库信息
     * 
     * @param projectId 项目库主键
     * @return 结果
     */
    @Override
    public int deleteA05ProjectByProjectId(String projectId)
    {
        return a05ProjectMapper.deleteA05ProjectByProjectId(projectId);
    }

    @Override
    public int batchInsertA05Project(List<A05Project> list) {
        list.forEach(s->s.setProjectId(String.valueOf(new SnowflakeIdUtils(5, 8).nextId())));
        return a05ProjectMapper.batchInsertA05Project(list);
    }

    @Override
    public int updateA05ProjectList(List<A05Project> a05Projects) {
        return a05ProjectMapper.updateA05ProjectList(a05Projects);
    }


    @Override
    public void downloadProjectFiles(List<String> projectIds, HttpServletResponse response) {
        // 过滤空值
        projectIds = projectIds.stream()
                .filter(StringUtils::isNotEmpty)
                .collect(Collectors.toList());
        List<A05Project> a05Projects = new ArrayList<>();
        if (projectIds.isEmpty()) {
            A05Project a05Project = new A05Project();
            a05Projects = a05ProjectMapper.selectA05ProjectList(a05Project);
            projectIds = a05Projects.stream().map(s -> s.getProjectId()).collect(Collectors.toList());
        }else {
            a05Projects = a05ProjectMapper.selectA05ListByIds(projectIds);
        }

        if (a05Projects.isEmpty()) {
            throw new RuntimeException("未找到对应的项目信息");
        }

        // 设置响应头
        setResponseHeader(response, "项目文件包.zip");


        List<A08PaymentReceipt> a08PaymentReceipts = a08PaymentReceiptMapper.selectA08ListByProjectIds(projectIds);
        Map<String, List<A08PaymentReceipt>> collect = a08PaymentReceipts.stream().collect(Collectors.groupingBy(A08PaymentReceipt::getProjectId));

        try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
            // 遍历每个项目，创建文件夹并添加文件
            for (A05Project project : a05Projects) {
                addProjectFilesToZip(project, zos,collect);
            }
            zos.flush();
        } catch (IOException e) {
            throw new RuntimeException("文件打包失败", e);
        }
    }

    /**
     * 设置响应头
     */
    private void setResponseHeader(HttpServletResponse response, String fileName) {
        try {
            // 对文件名进行URL编码，解决中文乱码问题
            String encodedFileName = URLEncoder.encode(fileName, "UTF-8")
                    .replaceAll("\\+", "%20");

            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);
            response.setCharacterEncoding("UTF-8");
        } catch (UnsupportedEncodingException e) {
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        }
    }

    /**
     * 将单个项目的文件添加到压缩包
     */
    private void addProjectFilesToZip(A05Project project, ZipOutputStream zos,Map<String, List<A08PaymentReceipt>> collect) throws IOException {
        String projectFolder = getProjectFolderName(project) + "/";
        // 添加各个文件
        addFileToZip(project.getFileOne(), "立项申请文件/", projectFolder, zos);
        addFileToZip(project.getFileTow(), "招投标信息文件/", projectFolder, zos);
        addFileToZip(project.getFileThree(), "合同信息文件/", projectFolder, zos);
        addFileToZip(project.getFileFour(), "项目总结文件/", projectFolder, zos);
        if(collect.containsKey(project.getProjectId())){
            List<A08PaymentReceipt> a08PaymentReceipts = collect.get(project.getProjectId());
            for (A08PaymentReceipt a08PaymentReceipt : a08PaymentReceipts) {
                if (a08PaymentReceipt.getType().equals("支出项")){
                    addFileToZip(a08PaymentReceipt.getFile(), "收款附件/收入项/", projectFolder, zos);
                }else if (a08PaymentReceipt.getType().equals("收入项")){
                    addFileToZip(a08PaymentReceipt.getFile(), "收款附件/支出项/", projectFolder, zos);
                }else {
                    throw new RuntimeException("收付款信息类型错误");
                }

            }
        }else {
            addFileToZip(project.getFileFive(), "收款附件/", projectFolder, zos);
        }
    }

    /**
     * 获取项目文件夹名称
     */
    private String getProjectFolderName(A05Project project) {
        // 使用项目编号和项目名称作为文件夹名
        String folderName = "";
        if (StringUtils.isNotEmpty(project.getProjectNumber())) {
            folderName += project.getProjectNumber();
        }
        if (StringUtils.isNotEmpty(project.getProjectName())) {
            if (StringUtils.isNotEmpty(folderName)) {
                folderName += "_";
            }
            folderName += project.getProjectName();
        }

        // 如果都没有，使用项目ID
        if (StringUtils.isEmpty(folderName)) {
            folderName = project.getProjectId();
        }

        return folderName;
    }

    /**
     * filePath 文件地址
     * displayName 文件夹名称
     * projectFolder 项目文件夹名称
     * 添加单个文件到压缩包
     */
    private void addFileToZip(String filePath, String displayName, String projectFolder, ZipOutputStream zos) {
        try {
            //创建文件夹
            zos.putNextEntry(new ZipEntry(projectFolder+displayName));
            zos.closeEntry();
            if (StringUtils.isEmpty(filePath)) {
                return;
            }
            //检查文件是否存在
            File file = new File(filePath);
            if (!file.exists() || !file.isFile()) {
                // 文件不存在，可以记录日志或跳过
                System.out.println("文件不存在: " + filePath);
                return;
            }
            //将文件输入到压缩包中

            // 获取文件扩展名
            String zipEntryName = projectFolder+displayName + file.getName();

            zos.putNextEntry(new ZipEntry(zipEntryName));

            try (FileInputStream fis = new FileInputStream(file)) {
                byte[] buffer = new byte[1024];
                int len;
                while ((len = fis.read(buffer)) > 0) {
                    zos.write(buffer, 0, len);
                }
            }

            zos.closeEntry();
        } catch (IOException e) {
            // 单个文件读取失败，继续处理其他文件
            log.error("读取文件失败: " + filePath + ", 错误: " + e.getMessage());
        }
    }

//    /**
//     * 获取文件扩展名
//     */
//    private String getFileExtension(String fileName) {
//        if (StringUtils.isEmpty(fileName)) {
//            return "";
//        }
//        int lastDotIndex = fileName.lastIndexOf(".");
//        return lastDotIndex > 0 ? fileName.substring(lastDotIndex) : "";
//    }


    @Override
    public String summary(A08PaymentReceipt a08PaymentReceipt) {
        List<A08PaymentReceipt> a08PaymentReceipts = a08PaymentReceiptMapper.selectA08PaymentReceiptList(a08PaymentReceipt);
        if (a08PaymentReceipts == null || a08PaymentReceipts.isEmpty()) {
            return "汇总成功";
        }
        // 计算支出项总额（排除null值）
        double expenditure = a08PaymentReceipts.stream()
                .filter(receipt -> A08TypeCommon.EXPENSE.equals(receipt.getType()))
                .map(A08PaymentReceipt::getAmount)
                .filter(Objects::nonNull)
                .mapToDouble(Double::doubleValue)
                .sum();

        // 计算收入项总额（排除null值）
        double income = a08PaymentReceipts.stream()
                .filter(receipt -> A08TypeCommon.INCOME.equals(receipt.getType()))
                .map(A08PaymentReceipt::getAmount)
                .filter(Objects::nonNull)
                .mapToDouble(Double::doubleValue)
                .sum();
        A05Project a05Project = a05ProjectMapper.selectA05ProjectByProjectId(a08PaymentReceipt.getProjectId());
        a05Project.setExpenseAmount(expenditure);
        a05Project.setPaymentAmount(income);
        a05ProjectMapper.updateA05Project(a05Project);
        return "汇总成功";
    }



}
